package com.enlorenz.common.geo.map;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.enlorenz.common.geo.base.GeoPoint;
import com.enlorenz.common.geo.base.IPoint;
import com.enlorenz.common.geo.map.base.MapConfig;
import com.enlorenz.common.geo.map.base.TileWrapper;
import com.enlorenz.common.geo.map.callback.IDownloadResultCallback;
import com.enlorenz.common.geo.map.callback.IProgressCallback;
import com.enlorenz.common.geo.map.callback.ITileMsgDisplayCallback;
import com.enlorenz.common.geo.map.common.MapConstants;
import com.enlorenz.common.geo.map.google.GoogleTileCmdConsole;
import com.enlorenz.common.geo.map.google.ITileCmdConsole;
import com.enlorenz.util.DataDetUtil;
import com.enlorenz.util.StringUtil;
import com.enlorenz.util.TimeUtil;

/**
 * 抽象的地图解析运行器
 * @author lcb
 */
public abstract class AbstractMapParserBaseRunner {
	
	/**
	 * 获取步进参数
	 * @return
	 */
	protected abstract String getStep();
	
	/**
	 * 获取是否显示Url信息
	 * @return
	 */
	protected abstract Boolean getDisplayUrl();
	
	/**
	 * 是否覆盖
	 * @return
	 */
	protected abstract Boolean getCover();
	
	/**
	 * 点集合
	 * @return
	 */
	protected abstract String getPointListStr();
	/**
	 * 缩放级别
	 * @return
	 */
	protected abstract String getZoom();
	/**
	 * 开启线程数
	 * @return
	 */
	protected abstract String getThreadNum();
	/**
	 * 输入目录
	 * @return
	 */
	protected abstract String getSrcFilePath();
	/**
	 * 输出目录
	 * @return
	 */
	protected abstract String getDstFilePath();
	/**
	 * 核心类路径
	 * @return
	 */
	protected abstract String getCoreClass();
	/**
	 * 模板Url
	 * @return
	 */
	protected abstract String getTemplateUrl();
	/**
	 * 下载失败图片的重试次数
	 * @return
	 */
	protected abstract String getPicTryTimes();
    /**
     * 创建参数配置
     * @param args	参数列表
     * @return
     */
    protected MapConfig createMapConfig(){
    	//地图配置
    	MapConfig mapConfig=new MapConfig();
    	 //点集合
        List<IPoint> pList=getPointList();
        mapConfig.setPointList(pList);
        //缩放级别
        mapConfig.setZoom(StringUtil.transStr2IntArr(getZoom(), 
        		MapConstants.MAP_LEVEL_SPLITOR));
        //开启线程数
        mapConfig.setThreadNum(Integer.valueOf(getThreadNum()));
        //输入目录
        mapConfig.setSrcFilePath(getSrcFilePath());
        //输出目录
        mapConfig.setDstFilePath(getDstFilePath());
        //核心类路径
        mapConfig.setCoreClass(getCoreClass());
        //模板Url
        mapConfig.setTemplateUrl(getTemplateUrl());
        //下载失败图片的重试次数
        mapConfig.setPicTryTimes(Integer.valueOf(getPicTryTimes()));
        //是否显示url
        mapConfig.setDisplayUrl(getDisplayUrl());
        //是否覆盖
        mapConfig.setCover(getCover());
        
        //设置步进
        mapConfig.setStep(getStep());
        return mapConfig;
    }
    
    /**
     * 打印标题
     */
    private void printTitleScreen(){
    	System.out.println("*************************************************");
    	System.out.println("**                                             **");
    	System.out.println("**                                             **");
    	System.out.println("**             MDC地图处理单元  Ver【"+MapConstants.MAP_VERSION+"】           **");
    	System.out.println("**                                             **");
    	System.out.println("**               by PantaniForever             **");
    	System.out.println("**                                             **");
    	System.out.println("*************************************************");
    	try {
			Thread.sleep(TimeUtil.SECOND_MILLI*1);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
    }
    
    /**
	 * 获取点列表
	 * @return
	 */
	protected List<IPoint> getPointList(){
		 //点集合
        List<IPoint> pList = new ArrayList<IPoint>();
        String [] pointStrArrs=getPointListStr().split(MapConstants.MAP_POINT_LIST_SPLITOR);
        for(String parr:pointStrArrs){
        	String [] point=parr.split(MapConstants.MAP_POINT_SPLITOR);
        	pList.add(new GeoPoint(Double.valueOf(point[0]), Double.valueOf(point[1])));
        }
        return pList;
	}
	
    public void doMap() throws Exception {
    	//打印标题
    	printTitleScreen();
    	//地图参数
    	final MapConfig mapConfig=createMapConfig();
        //输出信息回调函数
        mapConfig.setTileMsgDisplay(new ITileMsgDisplayCallback() {
            @Override
            public void display(String msg) {
            	System.out.println(msg);
            }
        });
        //执行进度回调函数
        mapConfig.setProgressCallBack(new IProgressCallback() {
			@Override
			public void progress(int index, long total) {
				//System.out.println(index+"/"+total);
			}
		});
        //下载结果回调函数
        final long [] msgarr=new long[4];
        mapConfig.setDownloadResultCallback(new IDownloadResultCallback() {
        	private Date date=null;
			@Override
			public void downloadResult(String threadName, int type, String msg,
					int index, long total, TileWrapper googleTileWrapper, String url,long costTime) {
				
				if(IDownloadResultCallback.RESULT_TYPE_SUCCESS_DOWNLOAD == type){
					msgarr[0]=msgarr[0]+1;
				}else if(IDownloadResultCallback.RESULT_TYPE_FAILED_DOWNLOAD == type
						|| IDownloadResultCallback.RESULT_TYPE_FAILED_WRITE_FILE == type){
					msgarr[1]=msgarr[1]+1;
				}
				
				msgarr[2]++;
				msgarr[3]+=costTime;
				double avgTime=msgarr[3]/(double)msgarr[2];
				long leftTimeMin=(long)(((total-index)*avgTime)/TimeUtil.MINUTE_MILLI);
				long leftTimeHour=leftTimeMin/60;
				long leftTimeDay=leftTimeHour/24;
				
				if(!mapConfig.isDisplayUrl()){
					url="";
				}
				
				System.out.println("!Running:["+MapConfig.getTypeDesc(type)+"]["
				+Thread.currentThread().getName()+"](Avg:"+avgTime+"ms)(Left:"+leftTimeMin+"min/"+leftTimeHour+"hour/"+leftTimeDay+"day)"+ msg+":"
						+ index + "/" + total + ":" + googleTileWrapper
						+ ":" + url);
				
				if(null == date){
					date=new Date();
				}else{
					Date nowDate=new Date();
					boolean over=TimeUtil.isDiffTimeOverCondition(date,nowDate, TimeUtil.MINUTE_MILLI);
					if(over){
						msgarr[2]=0;
						msgarr[3]=0;		
						date=nowDate;
					}
				}
				
				//System.out.println("成功:"+msgarr[0]+" * "+msgarr[1]);
			}
		});
        
        ITileCmdConsole tileCmdConsole = (ITileCmdConsole) Class.forName(mapConfig.getCoreClass()).newInstance();
        tileCmdConsole.setMapConfig(mapConfig);
        
       
        //如果是google解析器,则可以设置模板
        if(tileCmdConsole instanceof GoogleTileCmdConsole){
        	 String templateUrl=mapConfig.getTemplateUrl();
             if(!DataDetUtil.isStrEmpty(templateUrl)){
            	 GoogleTileCmdConsole cmdConsole=(GoogleTileCmdConsole)tileCmdConsole;
            	 cmdConsole.setUrlTemplate(templateUrl);
             }
        }
        
        //开始下载
        tileCmdConsole.doParse();
    }
}
